/**
 *All rights reserved. This material is confidential and proprietary to Tungsten.
 */
package tungsten.t.database.testcase.inf;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

/**
 * 测试用例的抽象实现类<br>
 * 
 * @author tracy
 * @date 2013-9-3
 * @version Uno
 */
public abstract class AbstractTestCase implements TestCase
{

    /**
     * 存储
     */
    protected Map<Integer, Method> testMethodMap;

    /**
     * 
     */
    public AbstractTestCase()
    {
        testMethodMap = new HashMap<Integer, Method>();
        int num = 0;
        for (Method method : this.getClass().getDeclaredMethods())
        {
            if (checkTestCaseMethod(method))
            {
                testMethodMap.put(++num, method);
            }
        }

    }

    /**
     * @see TestCase#testExecute(int,String[])
     */
    @Override
    public void testExecute(int methodNum, String... args)
    {
        try
        {
            if (testMethodMap.containsKey(methodNum))
            {
                Method executeMethod = testMethodMap.get(methodNum);
                StringBuffer sb = new StringBuffer("\n开始执行 ==> 【");
                sb.append(this.getDesc());
                sb.append("】.【");
                sb.append(executeMethod.getAnnotation(TestMethodAnnotation.class).desc());
                sb.append("】\t输入的参数：[ ");
                for (String arg : args)
                {
                    sb.append(arg);
                    sb.append(", ");
                }
                sb.append("]");
                System.err.println(sb);

                executeMethod.invoke(this, (Object) args);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * @see TestCase#listTestMethods()
     */
    @Override
    public StringBuffer listTestMethods()
    {
        StringBuffer sb = new StringBuffer();
        try
        {
            for (Integer methodNum : testMethodMap.keySet())
            {
                sb.append("\t ");
                sb.append(methodNum);
                sb.append(" : ");
                sb.append(testMethodMap.get(methodNum).getAnnotation(TestMethodAnnotation.class).desc());
                sb.append("\n");
            }

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return sb;
    }

    /**
     * @see TestCase#listMethodParams(int)
     */
    @Override
    public StringBuffer listMethodParams(int methodNum)
    {
        // TODO 目前参数列举的实现依赖于方法注解的标识，需要手动维护

        StringBuffer sb = new StringBuffer();

        if (testMethodMap.containsKey(methodNum))
        {
            TestMethodAnnotation methodAnnotation = testMethodMap.get(methodNum).getAnnotation(TestMethodAnnotation.class);
            sb.append(String.format("\t\t【%s】请输入参数, 空格隔开, # 表示结束输入, $ 返回\n",
                                    methodAnnotation.desc()));
            sb.append("\t\t参数列表:");
            sb.append(methodAnnotation.paramsDesc());
        }
        else
        {
            sb.append("\t\t请输入有效的方法编号!");
        }
        sb.append("\n");
        return sb;
    }

    /**
     * 检查方法是否为测试方法<br>
     * 
     * @param method
     * @return
     */
    private boolean checkTestCaseMethod(Method method)
    {
        return method.getName().startsWith("test")
                && Modifier.isPublic(method.getModifiers())
                && method.getReturnType().equals(Boolean.TYPE)
                && method.getAnnotation(TestMethodAnnotation.class) != null
                && !Modifier.isAbstract(method.getModifiers());

    }

}
